/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.weso.acota.appserv;


import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.weso.acota.enhacer.Enhancer;
import org.weso.acota.enhacer.GoogleEnhancer;
import org.weso.acota.enhacer.LuceneEnhancer;
import org.weso.acota.enhacer.OpenNLPEnhancer;
import org.weso.acota.to.RequestSuggestionTO;
import org.weso.acota.to.SuggestionTO;

/**
 *
 * @author  weena
 */
public class SuggestAppServ {

	private List<Enhancer> enhancers = new ArrayList<Enhancer>();
	protected static Logger logger = Logger.getLogger(SuggestAppServ.class);
	private SuggestionTO suggestSingleton;

    public SuggestAppServ(){    	
    	logger.info("Set the first enhancer (Lucene)");
    	this.enhancers.add(new LuceneEnhancer());
    	this.enhancers.add(new OpenNLPEnhancer());
    	this.enhancers.add(new GoogleEnhancer());
    	
    	logger.info("Set succesor (OpenNLP)");
    	this.enhancers.get(0).setSuccessor(this.enhancers.get(1));
    	
    	logger.info("Set succesor (Google)");
    	this.enhancers.get(1).setSuccessor(this.enhancers.get(2));
    	
    }
    
    public SuggestionTO suggestSingleton(RequestSuggestionTO request){
    	if(suggestSingleton!=null){
    		return suggestSingleton;
    	}else{
    		return setQuery(request);
    	}
    }
    
    public SuggestionTO setQuery(RequestSuggestionTO request){
    	logger.debug("Show all suggestions");
		SuggestionTO suggest = this.enhancers.get(0).enhance(request);
		OderedSuggestion(suggest);
		suggestSingleton = suggest;
        return suggestSingleton;
    }

	public SuggestionTO suggest(RequestSuggestionTO request) {
        return suggestSingleton(request);
    }
	
	public SuggestionTO suggestPaged(RequestSuggestionTO request,int page, int maxRegister ) {
		logger.debug("Show one page of suggestions");
		SuggestionTO suggest = suggestSingleton(request);
		Map<String,Integer> labelPaged = new LinkedHashMap<String, Integer>();
		int numberOfpagaes = (int) Math.ceil(suggest.getLabels().size()/maxRegister);
		logger.debug("Take care about the max limit");
		if(page>numberOfpagaes){
			page = numberOfpagaes;
		}
		logger.debug("Define limits of each page");
		int DonwLimit = page*maxRegister;
		int UpLimit = DonwLimit + maxRegister;
		int cont =0;
		
		logger.debug("Set a new map of labels depend of limts");
		@SuppressWarnings("rawtypes")
		Iterator itr = suggest.getLabels().entrySet().iterator();
		while (itr.hasNext()) {
			@SuppressWarnings("rawtypes")
			Map.Entry e = (Map.Entry)itr.next();
			if(cont>=DonwLimit && cont<UpLimit){
				labelPaged.put(e.getKey().toString(), 
						Integer.parseInt(e.getValue().toString()));
			}
			cont++;
		}
		suggest.setLabels(labelPaged);
        return suggest;
    }
	
	@SuppressWarnings("unchecked")
	public void OderedSuggestion(SuggestionTO suggest){
    	logger.debug("Get Suggstions order and limit");
		//order suggestions
		LinkedHashMap <String,Integer> labels = (LinkedHashMap<String, Integer>) suggest.getLabels();
		//sorted map
		LinkedHashMap <String,Integer> orderLabels = new LinkedHashMap<String, Integer>();
		//characters of tags - labels
		@SuppressWarnings("rawtypes")
		List values = new ArrayList<Integer>(labels.values());
		//ordered set
		Collections.sort(values);
		int tmp=0;
		for (int i= values.size()-1; i>=0;i--){
			tmp = (Integer) values.get(i);
			for( @SuppressWarnings("rawtypes") Map.Entry k : labels.entrySet())
			{
				int valueLabel = (Integer) k.getValue();
				if(tmp == valueLabel )
				{
					orderLabels.put((String) k.getKey(), (Integer) k.getValue());
				}
			}
		}	
		suggest.setLabels(orderLabels);
    }
}
